/**
 * <AiRmob-Framework; A simple augmented reality framework for android >
    Copyright (C) <2012>  <AiRmob Team>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package airmob.framework;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import airmob.framework.GPSMarker;
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Environment;

public class AiRmobFileManager {
	
	static Context mContext;
	
	static File root = Environment.getExternalStorageDirectory();
	public static File defaultDir = null;
	
	/**
	 * Creates a default folder for external Data on the device's SD card
	 * @param newFolder
	 */
	public static void createDefaultFolder(String newFolder){
		defaultDir = new File(root + "/" + newFolder);
		defaultDir.mkdir();
	}
	
	
	/**
	 * Write content into a file
	 * @param file
	 * @param content
	 * @throws IOException
	 */
	public static void writeToDefaultDir(String file, String content) throws IOException{
		
		if (defaultDir.canWrite()){			        
	        FileWriter writer = new FileWriter(defaultDir + "/" + file);
	        BufferedWriter out = new BufferedWriter(writer);
	        out.write(content);
	        out.close();
	    }
	}	

	/** 
	 * Read a file into a String
	 * @param file the filename relative to the application's default directory
	 * @return String
	 * @throws IOException
	 */
	public static String readFileFromDefaultDir( String file ) throws IOException {
	    BufferedReader reader = new BufferedReader( new FileReader (defaultDir + "/" + file));
	    String line  = null;
	    StringBuilder stringBuilder = new StringBuilder();
	    String ls = System.getProperty("line.separator");
	    while( ( line = reader.readLine() ) != null ) {
	        stringBuilder.append( line );
	        stringBuilder.append( ls );
	    }
	    reader.close();
	    return stringBuilder.toString();
	 }
	
	
	/**
	 * reads a file from the application-intern memory to a string
	 * @param context
	 * @param resource
	 * @return
	 * @throws IOException
	 */
	public static String  readInternFile(Context context, String resource) throws IOException{
		
		AssetManager assetManager = context.getAssets();
		InputStream InS = assetManager.open(resource);
		BufferedReader reader = new BufferedReader(new InputStreamReader(InS));
		
		String line  = null;
	    StringBuilder stringBuilder = new StringBuilder();
	    String ls = System.getProperty("line.separator");
	    while( ( line = reader.readLine() ) != null ) {
	        stringBuilder.append( line );
	        stringBuilder.append( ls );
	    }
	    reader.close();
	    return stringBuilder.toString();
	}
	
	
	
	/**
	 * Loads a GPSMarker file created by AiRmobGPSgetter. 
	 * @param filename
	 * @return a hashmap containing all GPSMarkers stored in the file
	 * @throws IOException
	 */
	public static HashMap<String, GPSMarker> loadGPSMarker(String filename) throws IOException{
		HashMap<String, GPSMarker> markerMap = new HashMap<String, GPSMarker>();
		
		// read in a file and pass it to an XML decoder
		Document doc = XMLfromString(readInternFile(mContext, "gps_marker/" + filename));
		
		// get the nodes containing GPSMarkers
		NodeList nodes = doc.getElementsByTagName("GPSMarker");

		GPSMarker marker = new GPSMarker("undefined", 0, 0, 0);
		
		// hand each GPSMarker to the map
		// use a GPSMarker's ID as key
		for (int i = 0; i < nodes.getLength(); i++) {
			Node e = nodes.item(i);
			marker.markerID = e.getAttributes().item(0).getNodeValue();
			marker.latitude = Double.parseDouble(e.getAttributes().item(1).getNodeValue());
			marker.longitude = Double.parseDouble(e.getAttributes().item(2).getNodeValue());
			marker.radius = Integer.parseInt(e.getAttributes().item(3).getNodeValue());
			markerMap.put(e.getAttributes().item(0).getNodeValue(), 
					new GPSMarker(e.getAttributes().item(0).getNodeValue(), Double.parseDouble(e.getAttributes().item(1).getNodeValue()), 
							Double.parseDouble(e.getAttributes().item(2).getNodeValue()), Integer.parseInt(e.getAttributes().item(3).getNodeValue())));
		}
		
		
		return markerMap;
	}
	
	
	// reads an XML formatted string and creates a Document object with the strings content
	private static Document XMLfromString(String xml){

		Document doc = null;

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	        try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
		        is.setCharacterStream(new StringReader(xml));
		        doc = db.parse(is); 

			} catch (ParserConfigurationException e) {
				System.out.println("XML parse error: " + e.getMessage());
				return null;
			} catch (SAXException e) {
				System.out.println("Wrong XML file structure: " + e.getMessage());
	            return null;
			} catch (IOException e) {
				System.out.println("I/O exeption: " + e.getMessage());
				return null;
			}

	    return doc;

	}

}
